Das Abschlussprojekt besteht aus zwei Teilen:
1. Teil - Datenanalyse
2. Teil - Dashboard
Vorweg: Hinweise und Organisation
Grobe Zusammenfassung der am Freitag besprochenen Anforderungen:
- vollständige Datenaufbereitung
- Dokumentation der Arbeitsschritte (in englisch oder deutsch)
- nachvollziehbare und aussagekräftige Erläuterungen über Vorgehensweise/Entscheidungen
- für die Bewertung: 3 verschiedenartige Plots (Plotfunktionen) benennen
(Plot 1: univariate Analyse, Plot 2: bivariate Analyse, Plot 3: multivariate Analyse)
- Customizing der Plots
- Analyse der Plots
- Coding
Für die Visualisierung haben wir die Bibliothek Plotly express bzw Plotly kennen gelernt.
Für den Fall, dass du in der EDA die Bibliothek Matplotlib verwenden möchtest, gelten folgende Anforderungen:
- objektorientierte Stil verwenden https://matplotlib.org/stable/users/explain/api_interfaces.html
- benötigte high-level Bibliotheken sind selbstständig zu recherchieren, zu installieren und einzuarbeiten
- für die EDA ist ein- und dieselbe Bibliothek zu verwenden
Treff ist Donnerstag um 14:30 Uhr im Hauptraum. Da werden wir die Unterlagen in dokumentensichere Formate umwandeln. Das machen wir zusammen. Danach habt ihr bis 15:30 Uhr zeit, eure zu bewertenden Unterlagen in den Projektabgabeordner hochzuladen.
Am Freitag erfolgt die Vorstellung der 3 Plots innerhalb des Zeitrahmens von 5min - (+-1min) ist dabei ok. Bewertet wird die Einhaltung des Zeitrahmes - dass das Anliegen innerhalb eines vorgegebenen Zeitrahmens vorgetragen wird.
Du arbeitest als Data Scientist bei der P-2-P-Plattform https://www.kiva.org/, die vor einem Jahr gegründet wurde. Nun wollt ihr euer Geschäft erweitern. Euer Team hat sich aufgeteilt und jeder Analyst hat einen Teilbereich der Daten. Deine Aufgabe ist es in einer explorativen Datenanalyse Insights für eure Plattform herauszufinden.
Euer Geschäftsmodell ist das Betreiben einer Plattform (crowd-investing) bei der sich Personen die eine Geschäftsidee haben, aber nicht das benötigte Geld, anmelden und für ihr Projekt innerhalb einer vorgegebenen Zeit Geld sammeln können.
Auf der anderen Seite habt ihr Geldgeber, die gern ihr Geld in Projekte anlegen möchten und nach Investitionen suchen.
Als Vermittler bringt eure Plattform also Geldnehmer und Geldgeber zusammen.
Deine Datenbasis ist die Historie eurer Plattform.
Getroffene Annahmen zu dem Geschäftsmodell
Alle Projekte sind abgeschlossene Projekte, d.h. die Zeit, um für sein Projekt Geld zu sammeln ist abgelaufen. Euer Geschäftsmodell sieht es vor, dass die gesammelten Gelder ausgezahlt werden, auch wenn der Zielbetrag nicht erreicht wurde.
Ihr verdient euer Geld mit einer Provision für jedes Projekt was auf eurer Plattform landet.
Der Geldgeber erhält einen Zins für die Geldleihe.
- funded_amount ... mit Ablauf der "Crowding"zeit erhaltener Betrag/ ausgezahlter Betrag in USD
- loan_amount ... Zielbetrag (Betrag dem man für das Projekt erreichen wollte) in USD
- activity ... Unterkategory zu dem das Ziel des Crowdprojektes thematisch gehört
- sector ... Oberkategory in den das Crowdprojektes Thema fällt
- use ... Kurzbeschreibung wofür das Geld verwendet werden soll
- country_code ... Ländercode nach ISO Norm
- country ... Ländername nach ISO Norm
- region ... Region
- currency ... Währung in den der funded_amount dann ausgezahlt wurde
- term in months ... Dauer über die der Kredit ausgezahlt werden soll
- lender_count ...Darlehensgeber (also wieviele Personen Geld für das Projekt gegeben haben)
- borrower_genders ... Geschlecht und Anzahl der Darlehensnehmer, also diejenigen die das Crowdprojekt initiiert haben
- repayment interval ... vertraglich vereinbarte Rückzahlungsmodalitäten/-rhythmus
Basierend auf den vorangegangenen Daten soll ein Dashboard erstellt werden.
Das Dashboard soll:
- mindestens 1 HTML component enthalten
- 1 Dash Core Component mit dem Daten ausgewählt werden können
- 1 Grafik, die sich in Abhängigkeit von der Datenauswahl ändert
Die interesanteste Buissnessfrage ist es ob ein Kredit zu stande gekommen ist oder nicht, und welche Faktoren dies beinhaltet. Hier möchte ich die Kunden in einzelne Gruppen aufteilen und nach Geschecht, Land und Gruppengröße untersuchen
Ein erfolgreiches Funding liegt im Interesse aller Beteiligter.
# Notwendige Biblioteken Einlesen
import numpy as np
import pandas as pd
import csv
import plotly.express as px
import plotly.graph_objects as go
# Einlesen der Daten
# Automatische feststellung des CSV-Dialektes
with open("data_abschlussprojekt.csv", 'r', newline='') as csv_file:
dialect = csv.Sniffer().sniff(csv_file.read(2048))
print("Sniff: ", dialect.delimiter, dialect.doublequote,
repr(dialect.lineterminator), dialect.quotechar)
# Einlesen in einen Panda DataFrame
df = pd.read_csv("data_abschlussprojekt.csv",
on_bad_lines="warn",
dialect=dialect,
index_col=0)
df
Sniff: # False '\r\n' "
| funded_amount | loan_amount | activity | sector | use | country_code | country | region | currency | term_in_months | lender_count | borrower_genders | repayment_interval | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 300.0 | 300.0 | Fruits & Vegetables | Food | To buy seasonal, fresh fruits to sell. | PK | Pakistan | Lahore | PKR | 12.0 | 12 | female | irregular |
| 1 | 575.0 | 575.0 | Rickshaw | Transportation | to repair and maintain the auto rickshaw used ... | PK | Pakistan | Lahore | PKR | 11.0 | 14 | female, female | irregular |
| 2 | 150.0 | 150.0 | Transportation | Transportation | To repair their old cycle-van and buy another ... | IN | India | Maynaguri | INR | 43.0 | 6 | female | bullet |
| 3 | 200.0 | 200.0 | Embroidery | Arts | to purchase an embroidery machine and a variet... | PK | Pakistan | Lahore | PKR | 11.0 | 8 | female | irregular |
| 4 | 400.0 | 400.0 | Milk Sales | Food | to purchase one buffalo. | PK | Pakistan | Abdul Hakeem | PKR | 14.0 | 16 | female | monthly |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 671200 | 0.0 | 25.0 | Livestock | Agriculture | [True, u'para compara: cemento, arenya y ladri... | PY | Paraguay | Concepción | USD | 13.0 | 0 | female | monthly |
| 671201 | 25.0 | 25.0 | Livestock | Agriculture | [True, u'to start a turducken farm.'] - this l... | KE | Kenya | NaN | KES | 13.0 | 1 | female | monthly |
| 671202 | 0.0 | 25.0 | Games | Entertainment | NaN | KE | Kenya | NaN | KES | 13.0 | 0 | NaN | monthly |
| 671203 | 0.0 | 25.0 | Livestock | Agriculture | [True, u'to start a turducken farm.'] - this l... | KE | Kenya | NaN | KES | 13.0 | 0 | female | monthly |
| 671204 | 0.0 | 25.0 | Livestock | Agriculture | [True, u'to start a turducken farm.'] - this l... | KE | Kenya | NaN | KES | 13.0 | 0 | female | monthly |
671205 rows × 13 columns
# Erste Infos ermitteln
df.info()
<class 'pandas.core.frame.DataFrame'> Index: 671205 entries, 0 to 671204 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 funded_amount 671205 non-null float64 1 loan_amount 671205 non-null float64 2 activity 671205 non-null object 3 sector 671205 non-null object 4 use 666972 non-null object 5 country_code 671197 non-null object 6 country 671205 non-null object 7 region 614405 non-null object 8 currency 671205 non-null object 9 term_in_months 671205 non-null float64 10 lender_count 671205 non-null int64 11 borrower_genders 666984 non-null object 12 repayment_interval 671205 non-null object dtypes: float64(3), int64(1), object(9) memory usage: 71.7+ MB
Der Datensatz enthält Nulldaten aber keine Auffälligkeiten im Datentyp.
# Sind die Spaltennamen richtig Formatiert?
df.columns
Index(['funded_amount', 'loan_amount', 'activity', 'sector', 'use',
'country_code', 'country', 'region', 'currency', 'term_in_months',
'lender_count', 'borrower_genders', 'repayment_interval'],
dtype='object')
Die Columns des Datensatzen enthalten keine Besonderheiten
# Beschreiben der Daten inkl. kategorischer Daten
df.describe(include='all')
| funded_amount | loan_amount | activity | sector | use | country_code | country | region | currency | term_in_months | lender_count | borrower_genders | repayment_interval | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 671205.000000 | 671205.000000 | 671205 | 671205 | 666972 | 671197 | 671205 | 614405 | 671205 | 671205.000000 | 671205.000000 | 666984 | 671205 |
| unique | NaN | NaN | 163 | 15 | 423452 | 86 | 87 | 12695 | 67 | NaN | NaN | 11298 | 4 |
| top | NaN | NaN | Farming | Agriculture | to buy a water filter to provide safe drinking... | PH | Philippines | Kaduna | PHP | NaN | NaN | female | monthly |
| freq | NaN | NaN | 72955 | 180302 | 5217 | 160441 | 160441 | 10000 | 160440 | NaN | NaN | 426502 | 342717 |
| mean | 785.995061 | 842.397107 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 13.739022 | 20.590922 | NaN | NaN |
| std | 1130.398941 | 1198.660073 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 8.598919 | 28.459551 | NaN | NaN |
| min | 0.000000 | 25.000000 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 1.000000 | 0.000000 | NaN | NaN |
| 25% | 250.000000 | 275.000000 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 8.000000 | 7.000000 | NaN | NaN |
| 50% | 450.000000 | 500.000000 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 13.000000 | 13.000000 | NaN | NaN |
| 75% | 900.000000 | 1000.000000 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 14.000000 | 24.000000 | NaN | NaN |
| max | 100000.000000 | 100000.000000 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 158.000000 | 2986.000000 | NaN | NaN |
Für die einzelnen Spalten läst sich feststellen:
funded_amount
loan_amount
activity
sector
use
country_code
country
region
currency
term_in_month
lender_count
borrow_gender
repayment_interval
print("Anzahl Duplikate:",
df.duplicated().sum(),
f"\nIn Prozent: {df.duplicated().mean()*100:.2f}%")
Anzahl Duplikate: 24588 In Prozent: 3.66%
Ansicht eines Auszuges der Duplicate.
df.loc[df.duplicated(), :]
| funded_amount | loan_amount | activity | sector | use | country_code | country | region | currency | term_in_months | lender_count | borrower_genders | repayment_interval | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 498 | 100.0 | 100.0 | Home Energy | Personal Use | to buy a solar-powered lamp. | SV | El Salvador | NaN | USD | 14.0 | 4 | male | monthly |
| 606 | 100.0 | 100.0 | Home Energy | Personal Use | to buy a solar-powered lamp. | SV | El Salvador | NaN | USD | 14.0 | 4 | male | monthly |
| 808 | 450.0 | 450.0 | Higher education costs | Education | to pay for one semester's registration fees. | CO | Colombia | Bogotà | COP | 7.0 | 15 | female | monthly |
| 1703 | 500.0 | 500.0 | Higher education costs | Education | To buy a laptop for educational purposes. | SO | Somalia | Hargeisa | USD | 8.0 | 19 | male | monthly |
| 2317 | 250.0 | 250.0 | Poultry | Agriculture | to purchase poultry. | KE | Kenya | Ndaragwa | KES | 16.0 | 10 | female | monthly |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 671200 | 0.0 | 25.0 | Livestock | Agriculture | [True, u'para compara: cemento, arenya y ladri... | PY | Paraguay | Concepción | USD | 13.0 | 0 | female | monthly |
| 671201 | 25.0 | 25.0 | Livestock | Agriculture | [True, u'to start a turducken farm.'] - this l... | KE | Kenya | NaN | KES | 13.0 | 1 | female | monthly |
| 671202 | 0.0 | 25.0 | Games | Entertainment | NaN | KE | Kenya | NaN | KES | 13.0 | 0 | NaN | monthly |
| 671203 | 0.0 | 25.0 | Livestock | Agriculture | [True, u'to start a turducken farm.'] - this l... | KE | Kenya | NaN | KES | 13.0 | 0 | female | monthly |
| 671204 | 0.0 | 25.0 | Livestock | Agriculture | [True, u'to start a turducken farm.'] - this l... | KE | Kenya | NaN | KES | 13.0 | 0 | female | monthly |
24588 rows × 13 columns
# Duplikate ohne Funding
df.loc[(df.duplicated()) & (df['funded_amount'] == 0), :]
| funded_amount | loan_amount | activity | sector | use | country_code | country | region | currency | term_in_months | lender_count | borrower_genders | repayment_interval | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 126605 | 0.0 | 350.0 | Personal Housing Expenses | Housing | NaN | SV | El Salvador | NaN | USD | 14.0 | 0 | NaN | monthly |
| 126675 | 0.0 | 350.0 | Personal Housing Expenses | Housing | NaN | SV | El Salvador | NaN | USD | 14.0 | 0 | NaN | monthly |
| 126788 | 0.0 | 125.0 | Clothing | Clothing | NaN | KE | Kenya | NaN | KES | 3.0 | 0 | NaN | bullet |
| 275942 | 0.0 | 325.0 | Grocery Store | Food | NaN | KE | Kenya | NaN | KES | 7.0 | 0 | NaN | bullet |
| 280683 | 0.0 | 325.0 | General Store | Retail | NaN | KE | Kenya | NaN | KES | 9.0 | 0 | NaN | bullet |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 671199 | 0.0 | 25.0 | Livestock | Agriculture | [True, u'para compara: cemento, arenya y ladri... | PY | Paraguay | Concepción | USD | 13.0 | 0 | female | monthly |
| 671200 | 0.0 | 25.0 | Livestock | Agriculture | [True, u'para compara: cemento, arenya y ladri... | PY | Paraguay | Concepción | USD | 13.0 | 0 | female | monthly |
| 671202 | 0.0 | 25.0 | Games | Entertainment | NaN | KE | Kenya | NaN | KES | 13.0 | 0 | NaN | monthly |
| 671203 | 0.0 | 25.0 | Livestock | Agriculture | [True, u'to start a turducken farm.'] - this l... | KE | Kenya | NaN | KES | 13.0 | 0 | female | monthly |
| 671204 | 0.0 | 25.0 | Livestock | Agriculture | [True, u'to start a turducken farm.'] - this l... | KE | Kenya | NaN | KES | 13.0 | 0 | female | monthly |
105 rows × 13 columns
print(f"Prozent von nicht erfolgreichen Duplicaten: {df.loc[(df.duplicated()) & (df['funded_amount'] == 0), :].shape[0] / df.loc[(df.duplicated()) , :].shape[0] * 100: .2f}%")
Prozent von nicht erfolgreichen Duplicaten: 0.43%
Insgesamt gibt es mit 24588 (3,66%) nur recht wenige Duplicate. Davon sind grade einmal 105 (0.43% von 24588) potenzielle Versuche das selbe nach einem nicht erfolgreichem Funding erneut zu funden. Die erfolgreichen doppelten Fundings lassen sich zudem nicht eindeutig als systemseitiger Doppeleintrag identifizieren da eindeutige Identifier wie eine Transaktionsnummer fehlen. Es ist warscheinlich das erfolgreiche Fundings eventuell mehrfach wiederholt wurden.
Deshalb werden die Doppeleinträge im Datensatz behalten.
Spalten mit NaN sind: use, country_code, region, borrow_gender
# Gesamtsumme der NaN Werte
df.isna().sum()
funded_amount 0 loan_amount 0 activity 0 sector 0 use 4233 country_code 8 country 0 region 56800 currency 0 term_in_months 0 lender_count 0 borrower_genders 4221 repayment_interval 0 dtype: int64
Eine behandlung der NaN Werte für use ist nicht notwendig da hier kein Text-Mining vorgenommen wird. Die für uns eventuell wichtige Info über den Verwendungszweck wird schon ausreichend in den Spalten activity und sector eingetragen. Text-Mining wird auserdem dadurch erschwehrt das verschiedene Sprachen verwendet werden. Sollte hier ein Machine Learning im Anschluss erfolgen dass das Verhalten der Kundengruppen anhand des Textes vorhersehen möchte, müßte die Spalte entsprechend aufbereitet werden, was wir hier aber auserhalb unserer technischen Möglichkeiten ist.
Deshalb kann die Spalte für die Analyse rausgenommen werden.
# Spalte use löschen
df.drop(columns="use", inplace=True)
df
| funded_amount | loan_amount | activity | sector | country_code | country | region | currency | term_in_months | lender_count | borrower_genders | repayment_interval | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 300.0 | 300.0 | Fruits & Vegetables | Food | PK | Pakistan | Lahore | PKR | 12.0 | 12 | female | irregular |
| 1 | 575.0 | 575.0 | Rickshaw | Transportation | PK | Pakistan | Lahore | PKR | 11.0 | 14 | female, female | irregular |
| 2 | 150.0 | 150.0 | Transportation | Transportation | IN | India | Maynaguri | INR | 43.0 | 6 | female | bullet |
| 3 | 200.0 | 200.0 | Embroidery | Arts | PK | Pakistan | Lahore | PKR | 11.0 | 8 | female | irregular |
| 4 | 400.0 | 400.0 | Milk Sales | Food | PK | Pakistan | Abdul Hakeem | PKR | 14.0 | 16 | female | monthly |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 671200 | 0.0 | 25.0 | Livestock | Agriculture | PY | Paraguay | Concepción | USD | 13.0 | 0 | female | monthly |
| 671201 | 25.0 | 25.0 | Livestock | Agriculture | KE | Kenya | NaN | KES | 13.0 | 1 | female | monthly |
| 671202 | 0.0 | 25.0 | Games | Entertainment | KE | Kenya | NaN | KES | 13.0 | 0 | NaN | monthly |
| 671203 | 0.0 | 25.0 | Livestock | Agriculture | KE | Kenya | NaN | KES | 13.0 | 0 | female | monthly |
| 671204 | 0.0 | 25.0 | Livestock | Agriculture | KE | Kenya | NaN | KES | 13.0 | 0 | female | monthly |
671205 rows × 12 columns
# Auflistung der NaN für county_code
df.loc[df["country_code"].isna(), :]
| funded_amount | loan_amount | activity | sector | country_code | country | region | currency | term_in_months | lender_count | borrower_genders | repayment_interval | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 202537 | 4150.0 | 4150.0 | Wholesale | Wholesale | NaN | Namibia | EEnhana | NAD | 6.0 | 162 | female | bullet |
| 202823 | 4150.0 | 4150.0 | Wholesale | Wholesale | NaN | Namibia | Rundu | NAD | 6.0 | 159 | male | bullet |
| 344929 | 3325.0 | 3325.0 | Wholesale | Wholesale | NaN | Namibia | EEnhana | NAD | 7.0 | 120 | female | bullet |
| 351177 | 3325.0 | 3325.0 | Wholesale | Wholesale | NaN | Namibia | Rundu | NAD | 7.0 | 126 | male | bullet |
| 420953 | 3325.0 | 3325.0 | Wholesale | Wholesale | NaN | Namibia | EEnhana | NAD | 7.0 | 118 | female | bullet |
| 421218 | 4000.0 | 4000.0 | Wholesale | Wholesale | NaN | Namibia | Rundu | NAD | 7.0 | 150 | male | bullet |
| 487207 | 5100.0 | 5100.0 | Renewable Energy Products | Retail | NaN | Namibia | Katima Mulilo | NAD | 7.0 | 183 | male | bullet |
| 487653 | 5000.0 | 5000.0 | Wholesale | Wholesale | NaN | Namibia | Oshakati | NAD | 7.0 | 183 | female | bullet |
# Auflistung aller Namibia Daten
df.loc[df["country"] == 'Namibia', :]
| funded_amount | loan_amount | activity | sector | country_code | country | region | currency | term_in_months | lender_count | borrower_genders | repayment_interval | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 202537 | 4150.0 | 4150.0 | Wholesale | Wholesale | NaN | Namibia | EEnhana | NAD | 6.0 | 162 | female | bullet |
| 202823 | 4150.0 | 4150.0 | Wholesale | Wholesale | NaN | Namibia | Rundu | NAD | 6.0 | 159 | male | bullet |
| 344929 | 3325.0 | 3325.0 | Wholesale | Wholesale | NaN | Namibia | EEnhana | NAD | 7.0 | 120 | female | bullet |
| 351177 | 3325.0 | 3325.0 | Wholesale | Wholesale | NaN | Namibia | Rundu | NAD | 7.0 | 126 | male | bullet |
| 420953 | 3325.0 | 3325.0 | Wholesale | Wholesale | NaN | Namibia | EEnhana | NAD | 7.0 | 118 | female | bullet |
| 421218 | 4000.0 | 4000.0 | Wholesale | Wholesale | NaN | Namibia | Rundu | NAD | 7.0 | 150 | male | bullet |
| 487207 | 5100.0 | 5100.0 | Renewable Energy Products | Retail | NaN | Namibia | Katima Mulilo | NAD | 7.0 | 183 | male | bullet |
| 487653 | 5000.0 | 5000.0 | Wholesale | Wholesale | NaN | Namibia | Oshakati | NAD | 7.0 | 183 | female | bullet |
Die NaN Werte in der Spalte country_code sind ausschlieslich für den Fall zu finden in dem country = Namibia gilt. Da der Ländercode für Namibia 'Na' ist, könnte hier ein Fehler beim Importieren passiert sein. Eventuell hat das System Na nicht richtig erkannt und mit einem Synonym für Null, NaN etc. verwechselt.
Desweiteren ist die country_code Spalte inhaltlich eine Kopie von country. Sie ist also theoretisch obsolet könnte aber für einen Geoplot noch verwendung finden .
Die Spalte country_code wird korrigiert und trotz dopplung behalten
# Korrigieren der NaN für Namibia
df.loc[df["country"] == 'Namibia', 'country_code'] = 'NA'
df.loc[df["country"] == 'Namibia', :]
| funded_amount | loan_amount | activity | sector | country_code | country | region | currency | term_in_months | lender_count | borrower_genders | repayment_interval | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 202537 | 4150.0 | 4150.0 | Wholesale | Wholesale | NA | Namibia | EEnhana | NAD | 6.0 | 162 | female | bullet |
| 202823 | 4150.0 | 4150.0 | Wholesale | Wholesale | NA | Namibia | Rundu | NAD | 6.0 | 159 | male | bullet |
| 344929 | 3325.0 | 3325.0 | Wholesale | Wholesale | NA | Namibia | EEnhana | NAD | 7.0 | 120 | female | bullet |
| 351177 | 3325.0 | 3325.0 | Wholesale | Wholesale | NA | Namibia | Rundu | NAD | 7.0 | 126 | male | bullet |
| 420953 | 3325.0 | 3325.0 | Wholesale | Wholesale | NA | Namibia | EEnhana | NAD | 7.0 | 118 | female | bullet |
| 421218 | 4000.0 | 4000.0 | Wholesale | Wholesale | NA | Namibia | Rundu | NAD | 7.0 | 150 | male | bullet |
| 487207 | 5100.0 | 5100.0 | Renewable Energy Products | Retail | NA | Namibia | Katima Mulilo | NAD | 7.0 | 183 | male | bullet |
| 487653 | 5000.0 | 5000.0 | Wholesale | Wholesale | NA | Namibia | Oshakati | NAD | 7.0 | 183 | female | bullet |
# Welche einzigartigen Regionen mit NaN Werten gibt es
pd.unique(df.loc[df['region'].isna(), 'country'])
array(['Kenya', 'El Salvador', 'Senegal', 'Iraq', 'United States', 'Peru',
'Tanzania', 'Guatemala', 'Colombia', 'Indonesia', 'Kosovo',
'Timor-Leste', 'Turkey', 'Philippines', 'Palestine', 'Burundi',
'Tajikistan', 'Honduras', 'Jordan', 'Mexico', 'Lebanon', 'Albania',
'Nicaragua', 'Bolivia', 'Israel', 'Rwanda', 'Azerbaijan',
'Ecuador', 'Mongolia', 'Haiti', 'Cambodia', 'Sierra Leone',
'Yemen', 'Zimbabwe', 'Paraguay', 'Uganda', 'Armenia',
'Dominican Republic', 'Benin', 'Belize', 'Ghana', 'Mozambique',
'Zambia', 'Samoa', 'Brazil', 'Panama', 'Pakistan', 'Burkina Faso',
'Suriname', 'Virgin Islands', 'Togo', 'South Africa', 'Malawi',
'Nigeria', 'Liberia', 'Vietnam', 'Costa Rica', 'Guam',
'Myanmar (Burma)', 'Mali', 'Madagascar',
'The Democratic Republic of the Congo', 'Cameroon', 'Georgia',
'Puerto Rico', 'South Sudan', 'Moldova', 'Chile', 'Kyrgyzstan',
'India', 'China', 'Bhutan'], dtype=object)
# Erstellen der Länderlist mit der Anzahl der fehlenden Regionen
mis_reg = df.loc[df['region'].isna(),'country'].value_counts()
mis_reg.head(36)
country El Salvador 20251 Kenya 8752 Rwanda 6138 United States 5173 Senegal 3231 Lebanon 1823 Turkey 1687 Kosovo 1419 Indonesia 1065 Iraq 993 Colombia 777 Mexico 706 Cameroon 692 Nicaragua 640 Benin 495 Madagascar 430 Albania 315 Uganda 211 Azerbaijan 170 Peru 160 Tanzania 127 Sierra Leone 119 Guatemala 99 Tajikistan 98 Bolivia 97 Palestine 89 Liberia 82 Philippines 81 Ghana 79 Honduras 71 Puerto Rico 68 Paraguay 62 Zimbabwe 57 Burundi 56 India 43 Brazil 41 Name: count, dtype: int64
mis_reg.tail(36)
country Ecuador 37 South Sudan 36 Haiti 36 Zambia 34 Malawi 31 Jordan 29 Cambodia 25 Samoa 24 Costa Rica 18 Dominican Republic 18 Mozambique 15 Timor-Leste 14 Israel 10 Togo 7 Burkina Faso 6 Myanmar (Burma) 6 Nigeria 6 Mali 5 Armenia 5 Pakistan 5 Yemen 5 Suriname 4 The Democratic Republic of the Congo 4 Mongolia 4 Vietnam 3 Virgin Islands 2 Panama 2 South Africa 2 Belize 2 Moldova 2 Kyrgyzstan 1 China 1 Georgia 1 Chile 1 Guam 1 Bhutan 1 Name: count, dtype: int64
# Betrachtung von El Salvador
df.loc[df['country'].isin(['El Salvador']), 'region'].value_counts()
region San Miguel 2737 Gotera 2300 Usulután 2231 Ciudad El Triunfo 2176 El Transito 1842 Osicala 1712 La Unión 1615 Sensuntepeque 1194 Anamoros 1074 Ciudad Barrios 982 Jiquilisco 707 San Vicente 675 San Miguel, San Miguel 68 San Rafael de Oriente, San Miguel 35 San Francisco Gotera, Morazan 30 Corinto, Morazan 29 Zacatecoluca 26 Jiquilisco, Usulutan 22 El Transito, San Miguel 18 San Carlos, Morazan 18 Jucuapa, Usulutan 15 El Divisadero, Morazan 14 Guatajiagua, Morazan 14 Lolotiquillo, Morazan 10 La Libertad 9 Ahuachapan 9 San Jorge, San Miguel 8 Concepcion Batres, Usulutan 7 Chilanga, Morazan 7 jocoaitique,Morazan 4 Santa Ana 4 Osicala, Morazan 3 Sonsonate 2 San Buena Ventura, Usulutan 2 Meanguera, Morazan 2 Yamabal, Morazan 2 Chinameca, San Miguel 2 Delicias de Concepcion, Morazan 2 Cacaopera, Morazan 2 Semsembra, Morazan 2 Gualococti, Morazan 2 San Isidro, Morazán 1 La Libertad, La Libertad 1 Chalatenango, Chalatenango 1 San Simon Morazan. 1 Berlin, Usulutan 1 La Palma 1 Joateca, Morazán 1 Moncagua, San Miguel. 1 Yoloaiquin, Morazan 1 Canton San Francisco, San Simon, Morazan. 1 Santiago de Maria, Usulutan 1 Name: count, dtype: int64
Anhand des Falles mit dem Land in denen am meisten die Region fehlt, El Salvadore, zeigt sich das eine einfacher Zusammenhang zwischen country und region nicht besteht. Da wir nicht fein in die einzelnen Länder bei unserer Analyse reinschauen und die Region nicht einfach ermitteln können und diese erstmal nicht benötigen, können wir die NaN Einträge hier ignorieren.
Die Spalte region ist für unsere Analyse zu feingliedrig, da wir erstmal global betrachen. Sie kann für unsere Analyse erstmal gelöscht weren
# Löschen der Spalte region
df.drop(columns='region', inplace=True)
df
| funded_amount | loan_amount | activity | sector | country_code | country | currency | term_in_months | lender_count | borrower_genders | repayment_interval | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 300.0 | 300.0 | Fruits & Vegetables | Food | PK | Pakistan | PKR | 12.0 | 12 | female | irregular |
| 1 | 575.0 | 575.0 | Rickshaw | Transportation | PK | Pakistan | PKR | 11.0 | 14 | female, female | irregular |
| 2 | 150.0 | 150.0 | Transportation | Transportation | IN | India | INR | 43.0 | 6 | female | bullet |
| 3 | 200.0 | 200.0 | Embroidery | Arts | PK | Pakistan | PKR | 11.0 | 8 | female | irregular |
| 4 | 400.0 | 400.0 | Milk Sales | Food | PK | Pakistan | PKR | 14.0 | 16 | female | monthly |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 671200 | 0.0 | 25.0 | Livestock | Agriculture | PY | Paraguay | USD | 13.0 | 0 | female | monthly |
| 671201 | 25.0 | 25.0 | Livestock | Agriculture | KE | Kenya | KES | 13.0 | 1 | female | monthly |
| 671202 | 0.0 | 25.0 | Games | Entertainment | KE | Kenya | KES | 13.0 | 0 | NaN | monthly |
| 671203 | 0.0 | 25.0 | Livestock | Agriculture | KE | Kenya | KES | 13.0 | 0 | female | monthly |
| 671204 | 0.0 | 25.0 | Livestock | Agriculture | KE | Kenya | KES | 13.0 | 0 | female | monthly |
671205 rows × 11 columns
print("Anzahl fehlender Werte Gender:", df["borrower_genders"].isna().sum())
print(f"Prozent {df.borrower_genders.isna().sum() / df.size * 100: .4f}%")
Anzahl fehlender Werte Gender: 4221 Prozent 0.0572%
# Erstellen eines überlagernden Histogrames um besser auffälligkeiten bei der verteilung von NaN werten zu sehen
mask = df["borrower_genders"].isnull()
fig = go.Figure()
fig.add_trace(go.Histogram(x=df.loc[mask, "country"], name="Fehlende Gender"))
fig.add_trace(go.Histogram(x=df.loc[~mask, "country"],
name="Gender angegeben"))
fig.update_yaxes(type="log")
fig.update_layout(width=1000, height=800, barmode='stack')